﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CanDoo;
using CanDoo.Core;
using CanDoo.Core.Data;
using CanDoo.Data;
using CanDoo.Extensions;
using CanDoo.Oil.Core.Contracts;
using CanDoo.Oil.Core.Models;
using CanDoo.Oil.Core.DTOs;

namespace CanDoo.Oil.Core.Services
{
    /// <summary>
    /// 业务实现——客户退货单
    /// </summary>
    public class OutSellBackService : CanDoo.Data.Entity.Services.ServiceBase<OutSellBack>, IOutSellBackContract
    {
        public IStockContract StockContract { get; set; }
        public IOutStoreContract OutStoreContract { get; set; }
        public ISerialNumContract SerialNumContract { get; set; }
        public IOilSerialNumContract OilSerialNumContract { get; set; }
        public ISellBillContract SellBillContract { get; set; }
        public ISerialNumTempContract SerialNumTempContract { get; set; }
        public OutSellBackService()
        {
        
        }


        public OrderApiDto SendPDAInfo(string Code)
        {
            var orderApiDto = new OrderApiDto();
            using (var scope = DbScopeFactory.CreateReadOnly())
            {
                var Entity = Entities.FirstOrDefault(p => p.Code == Code);
                if (Entity == null)
                    throw new Exception("销售退货单[" + Code + "]不存在");

                if (Entity.PassState == PassState.Pass)
                    throw new Exception("销售退货单[" + Code + "]已通过审核");

                orderApiDto.oId = Entity.Code;
                orderApiDto.oType = "销售退货单";
                orderApiDto.oWarehouse = Entity.Warehouse.Name;
                orderApiDto.oSupplier = Entity.Customer.Name;

                var proList = new List<OrderApiDtoItem>();


                var detailList = Entity.OutSellBackDetails.Where(p => p.Product.ManageSerialNum == true);
                foreach (var m in detailList)
                {
                    var detail = new OrderApiDtoItem();
                    detail.id = m.Product.SN;
                    detail.name = m.Product.Name;
                    detail.model = m.Product.Model;
                    detail.status = 0;
                    if (m.Product.ProductClass == 0)
                    {
                        var num = SerialNumContract.Entities.Where(p => p.OutSellBackId == Entity.Id && p.ProductId == m.Product.Id && p.Status == 6).Count();
                        //detail.count = (m.Num - num).ToInt();
                        detail.count = m.Num.ToInt();

                    }
                    else if (m.Product.ProductClass == 1)
                    {
                        var num = OilSerialNumContract.Entities.Where(p => p.OutSellBackId == Entity.Id && p.ProductId == m.Product.Id && p.Status == OilSerialStatus.WaitBack).Count();
                        //detail.count = (m.Num - num).ToInt();
                        detail.count = m.Num.ToInt();

                    }
                    proList.Add(detail);
                }
                orderApiDto.List = proList;
            }
            return orderApiDto;
        }


        public OperationResult GetPDAData(OrderApiDto orderApiDto)
        {
            var result = OperationResult.Success;
            var serialNumTempList = new List<SerialNumTemp>();

            using (var scope = DbScopeFactory.Create())
            {
                var entity = Entities.FirstOrDefault(p => p.Code == orderApiDto.oId);
                if (entity == null)
                {
                    result.ResultType = OperationResultType.Error;
                    result.Message = "销售退货单[" + orderApiDto.oId + "]不存在";
                    return result;
                }

                if (entity.PassState == PassState.Pass)
                {
                    result.ResultType = OperationResultType.Error;
                    result.Message = "销售退货单[" + orderApiDto.oId + "]已通过审核";
                    return result;
                }

                foreach (var m in orderApiDto.List)
                {
                    var detail = entity.OutSellBackDetails.First(p => p.Product.SN == m.id && p.Product.ManageSerialNum == true);
                    if (detail == null)
                    {
                        result.ResultType = OperationResultType.Error;
                        result.Message = "产品[" + m.name + "]不存在";
                        return result;
                    }
                    var productClass = detail.Product.ProductClass;

                    foreach (var n in m.list)
                    {
                        if (productClass == 0)
                        {
                            var mEntity = SerialNumContract.Entities.FirstOrDefault(p => p.SerialNumber == n);
                            if (mEntity != null)
                            {
                                if (mEntity.Status != 5)
                                {
                                    result.ResultType = OperationResultType.Error;
                                    result.Message = "序列号[" + n + "]不为销售出库状态";
                                    return result;
                                }
                                else
                                {
                                    mEntity.OutSellBackId = entity.Id;
                                    mEntity.Status = 6;
                                    SerialNumContract.Update(mEntity);
                                }
                            }
                            else
                            {
                                result.ResultType = OperationResultType.Error;
                                result.Message = "序列号[" + n + "]不存在";
                                return result;
                            }
                        }
                        else if (productClass == 1)
                        {
                            var mEntity = OilSerialNumContract.Entities.FirstOrDefault(p => p.SerialNumber == n);
                            if (mEntity != null)
                            {
                                if (mEntity.Status != OilSerialStatus.PassOut)
                                {
                                    result.ResultType = OperationResultType.Error;
                                    result.Message = "序列号[" + n + "]不为审核出库状态";
                                    return result;
                                }
                                else
                                {
                                    mEntity.OutSellBackId = entity.Id;
                                    mEntity.Status = OilSerialStatus.WaitBack;
                                    OilSerialNumContract.Update(mEntity);
                                }
                            }
                            else
                            {
                                result.ResultType = OperationResultType.Error;
                                result.Message = "序列号[" + n + "]不存在";
                                return result;
                            }
                        }
                    }
                }
                
                //SerialNumTempContract.AddEntity(serialNumTempList);
                return scope.SaveChanges() > 0 ? OperationResult.Success : OperationResult.NoChanged;
            }
        }

        public string GetNewCode()
        {
            var startStr = "XSTH";
            var dateStr = DateTime.Now.ToString("yyMMdd");
            var codePrefix = startStr + dateStr;

            //生成新单据号
            var newCode = "";
            var entity = Entities.Where(p => p.Code.StartsWith(codePrefix)).OrderByDescending(p => p.Code).FirstOrDefault();
            if (entity == null)
                newCode = codePrefix + "0001";
            else
                newCode = startStr + (int.Parse(entity.Code.Substring(startStr.Length)) + 1);
            return newCode;
        }

        public override OperationResult DeleteEntity(long id)
        {
            using (var scope = DbScopeFactory.Create())
            {
                

                var serialNumList = SerialNumContract.Entities.Where(p => p.OutSellBackId == id);
                var oilSerialNumList = OilSerialNumContract.Entities.Where(p => p.OutSellBackId == id);
                foreach (var m in serialNumList)
                {
                    if (m.Status != 6)
                        throw new Exception("序列号[" + m.SerialNumber + "]状态不允许删除");
                    m.Status = 5;
                    m.OutSellBackId = null;
                    SerialNumContract.Update(m);
                }
                foreach (var m in oilSerialNumList)
                {
                    if (m.Status != OilSerialStatus.WaitOut)
                        throw new Exception("序列号[" + m.SerialNumber + "]状态不允许删除");
                    m.Status = OilSerialStatus.PassOut;
                    m.OutSellBackId = null;
                    OilSerialNumContract.Update(m);
                }

                base.DeleteEntity(id);

                return scope.SaveChanges() > 0 ?
                    new OperationResult(OperationResultType.Success, $"删除1条记录!") :
                    new OperationResult(OperationResultType.NoChanged);
            }
        }

        public override OperationResult PassEntity(long entityId)
        {
            //TODO : 正式用之前 要检查每次需要序列号商品的数量  序列号数量不对的时候不允许审核通过
            //InOrder表更新采购单的入库数量 入库金额
            //InOrderDetails表更新每个产品的入库数量 入库金额
            //InStore表更新PassState状态
            //读取SeriesNumTemp表数据 插入对应的序列号表 并更新Status为审核入库
            //Stock表 更新每种产品的库存
            var entity = new OutSellBack();
            var count = 0;

            using (var scope = DbScopeFactory.Create())
            {
                entity = GetById(entityId);

                if (entity.PassState == PassState.Pass || entity.PassState == PassState.UnPass)
                    return new OperationResult(OperationResultType.Error, "此数据已通过审核");

                base.PassEntity(entityId);

                foreach (var m in entity.OutSellBackDetails)
                {
                    if (m.Product.ManageSerialNum)
                    {
                        var num = 0;
                        if (m.Product.ProductClass == 0)
                        {
                            var serialNumList = SerialNumContract.Entities.Where(p => p.ProductId == m.ProductId && p.OutSellBackId == entity.Id && p.Status == 6);
                            num = serialNumList.Count();
                            if (num != m.Num)
                                throw new Exception("产品[" + m.Product.Name + "]数量不匹配，出库数量为[" + m.Num + "],序列号数量为[" + num + "]");
                            else
                            {
                                foreach (var n in serialNumList)
                                {
                                    n.Status = 7;
                                    //n.OutSellBackId = entityId;
                                    //n.OutStoreId = entity.Id;
                                    //n.OutStoreTypeId = 2559210030104576;
                                    SerialNumContract.UpdateEntity(n);
                                }

                            }
                        }
                        else if (m.Product.ProductClass == 1)
                        {
                            var oilSerialNumList = OilSerialNumContract.Entities.Where(p => p.ProductId == m.ProductId && p.OutSellBackId == entity.Id && p.Status == OilSerialStatus.WaitBack);
                            num = oilSerialNumList.Count();
                            if (num != m.Num)
                                throw new Exception("产品[" + m.Product.Name + "]数量不匹配，出库数量为[" + m.Num + "],序列号数量为[" + num + "]");
                            else
                            {
                                foreach (var n in oilSerialNumList)
                                {
                                    n.Status = OilSerialStatus.Back;
                                    //n.OutSellBackId = entityId;
                                    //n.OutStoreId = entity.Id;
                                    //n.OutStoreTypeId = 2559210030104576;
                                    OilSerialNumContract.UpdateEntity(n);
                                }
                            }
                        }
                    }
                }

                PassStock(entity);

                SellBillContract.CreateBill(entity);

                count = scope.SaveChanges();
            }

            if (count > 0)
            {
                if (entity.OutStoreId != null)
                {
                    OutStoreContract.UpdateNum(entity.OutStoreId.ToLong());
                }
                return new OperationResult(OperationResultType.Success, $"审核通过1条记录!");
            }
            else
            {
                return new OperationResult(OperationResultType.NoChanged);
            }
        }

        public override OperationResult UnPassEntity(long entityId)
        {
            //TODO : 正式用之前 是否有序列号已经出库，如果存在已出库的数据就不允许撤销了  是否存在对应的已结算应付账单 存在也不允许撤销

            //InOrder表更新采购单的入库数量 入库金额
            //InOrderDetails表更新每个产品的入库数量 入库金额
            //InStore表更新PassState状态
            //读取SeriesNumTemp表数据 插入对应的序列号表 并更新Status为审核入库
            //Stock表 更新每种产品的库存
            var entity = new OutSellBack();
            var count = 0;

            using (var scope = DbScopeFactory.Create())
            {
                entity = GetById(entityId);
                if (entity.PassState == PassState.UnPass || entity.PassState == PassState.Wait)
                    return new OperationResult(OperationResultType.Error, "此数据未通过审核");

                base.UnPassEntity(entityId);
                UnPassStock(entity);

                SerialNumTempContract.UnPassOutSellBack(entity.Id);

                SellBillContract.DeleteBill(entity.Id);

                count = scope.SaveChanges();
                
            }
            if (count > 0)
            {
                if (entity.OutStoreId != null)
                {
                    OutStoreContract.UpdateNum(entity.OutStoreId.ToLong());
                }
                return new OperationResult(OperationResultType.Success, $"审核通过1条记录!");
            }
            else
            {
                return new OperationResult(OperationResultType.NoChanged);
            }
        }

        public OperationResult PassStock(OutSellBack entity)
        {
            var result = new OperationResult(OperationResultType.NoChanged);
            using (DbScopeFactory.Create())
            {
                var outSellBackDetails = entity.OutSellBackDetails;
                var productItemList = new List<ProductItem>();
                foreach (var m in outSellBackDetails)
                {
                    productItemList.Add(EntityChange(m));
                }
                StockContract.InToStore(entity.Warehouse, productItemList, true);
            }
            return result;
        }

        public OperationResult UnPassStock(OutSellBack entity)
        {
            var result = new OperationResult(OperationResultType.NoChanged);
            using (DbScopeFactory.Create())
            {
                var outSellBackDetails = entity.OutSellBackDetails;
                var productItemList = new List<ProductItem>();
                foreach (var m in outSellBackDetails)
                {
                    productItemList.Add(EntityChange(m));
                }
                StockContract.OutFromStore(entity.Warehouse, productItemList, true);
            }
            return result;
        }

        public ProductItem EntityChange(OutSellBackDetail m)
        {
            var ItemEntity = new ProductItem();
            ItemEntity.Id = m.Id;
            ItemEntity.Code = m.Product.Code;
            ItemEntity.SN = m.Product.SN;
            ItemEntity.Specifications = m.Product.Specifications;
            ItemEntity.ProductId = m.Product.Id;
            ItemEntity.Product = m.Product;
            ItemEntity.Name = m.Product.ShortName;
            ItemEntity.Model = m.Product.Model;
            ItemEntity.Num = m.Num;
            ItemEntity.Unit = m.Product.ProductUnit.Name;
            ItemEntity.Price = m.Price;
            ItemEntity.Money = m.Num * m.Price;
            ItemEntity.ChangeNum = m.AlreadyNum;
            ItemEntity.ChangeMoney = m.AlreadyMoney;
            ItemEntity.Coefficient = -1;
            return ItemEntity;
        }
    }
}
